# coding=utf-8
from string import Template
from utils.templete_file import TempleteFile


enum_item_templete=Template(
"""
${desc}
    ${item}"""
)

class EnumItem:

    def __init__(self, name: str, value: str, desc: str = None) -> None:
        self.name = name.strip()
        self.value = value.strip()
        self.description = desc

    def __str__(self) -> str:
        return enum_item_templete.substitute(
            desc=self.description if self.description is not None else "",
            item="{0} = {1}".format(self.name, self.value)
        )


enum_class_templete = Template(
"""
enum class ${TypeName}:${super} {${values}
};
"""
)


namespace_templete = Template(
"""
namespace ${name}{
    ${items}
}"""
)

class NameSpace(TempleteFile):

    def __init__(self, namespace) -> None:
        self.namespace = namespace
        self.container=[]

    def addTemplete(self,temp):
        self.container.append(temp)

    def __str__(self) -> str:
        return namespace_templete.substitute(name=self.namespace, items="\n".join([member.__str__() for member in self.container]))

class EnumClass(TempleteFile):

    def __init__(self, type_name, super) -> None:
        self.type_name = type_name
        self.super = super
        self.values = []

    def addValue(self, name: str, value: str):
        self.values.append("{0} = {1}".format(name.strip(), value.strip()))

    def addEmunItem(self, item: EnumItem):
        self.values.append(item.__str__())

    def __str__(self) -> str:
        return enum_class_templete.substitute(TypeName=self.type_name, super=self.super, values=",\n".join(self.values))

c_struct_templete = Template(
"""
${pragma_start}
${typedef}struct ${name} {${member}
    ${properties}

}${name1};
${pragma_end}
"""
)


class CStruct(TempleteFile):

    def __init__(self, typeName: str, typedef: bool = False, memory=None) -> None:
        self.typeName = typeName
        self.typedef = typedef
        self.memory = memory
        self.properties = []
        self.type = None

    def property(self, property: str):
        self.properties.append(property+";")


    def member(self, type: TempleteFile):
        self.type = type

    def __str__(self) -> str:
        return c_struct_templete.substitute(
            typedef="" if self.typedef is False else "typedef ",
            name=self.typeName,
            name1="" if self.typedef is False else self.typeName[1:] if self.typeName.startswith(
                "_") else self.typeName,
            properties="" if len(self.properties) == 0 else self.properties[0] if len(
                self.properties) == 1 else "\n\t".expandtabs(4).join(self.properties),
            member=self.type.__str__() if self.type is not None else "",
            pragma_start="#pragma pack({0})".format(
                self.memory) if self.memory is not None else "",
            pragma_end="#pragma pack()" if self.memory is not None else ""
        )


enum_templete = Template(
"""
enum ${name} {
    ${properties}
};
"""
)


class CEnum(TempleteFile):
    def __init__(self, typeName) -> None:
        self.typeName = typeName
        self.members = []

    def property(self, name: str, value: str):
        self.members.append("{0} = {1}".format(name, value))

    def __str__(self) -> str:
        return enum_templete.substitute(name=self.typeName, properties=",\n\t".expandtabs(4).join(self.members))




cpp_class_templete = Template(
"""
class ${class_name}${supper}{
    
};
"""
)